package com.qiaoba.module.generator.util;


import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.base.constant.BaseConstant;
import com.qiaoba.common.base.util.ArrayUtil;
import com.qiaoba.module.generator.config.GeneratorConfig;
import com.qiaoba.module.generator.constant.GenConstants;
import com.qiaoba.module.generator.entity.GeneratorTable;
import com.qiaoba.module.generator.entity.GeneratorTableColumn;
import com.qiaoba.module.generator.entity.vo.TableColumnVo;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * GeneratorUtil
 *
 * @author ailanyin
 * @date 2023-10-4 11:23:13
 */
public class GeneratorUtil {

    public static GeneratorTableColumn initColumn(TableColumnVo vo, String tableId) {
        GeneratorTableColumn column = new GeneratorTableColumn();
        column.setTableId(tableId);
        column.setSort(vo.getSort());
        column.setColumnName(vo.getColumnName());
        column.setColumnComment(vo.getColumnComment());
        // 设置java字段名
        column.setJavaField(StrUtil.toCamelCase(column.getColumnName()));
        // 设置默认类型
        column.setJavaType(GenConstants.TYPE_STRING);
        column.setQueryType(GenConstants.QUERY_EQ);
        column.setColumnType(vo.getColumnType());
        setType(column, vo.getColumnType());

        column.setIsPk(vo.getIsPk());
        column.setIsRequired(vo.getIsRequired());
        // (排除基类字段)
        if (!ArrayUtil.contains(GenConstants.COLUMN_NAME_NOT_HANDLE, column.getColumnName()) && !BaseConstant.YES.equals(column.getIsPk())) {
            column.setIsInsert(GenConstants.REQUIRE);
            column.setIsEdit(GenConstants.REQUIRE);
            column.setIsList(GenConstants.REQUIRE);

        }

        // 模糊查询字段
        if (ArrayUtil.containsValueIgnoreCase(GenConstants.LIKE_COLUMN, column.getColumnName())) {
            column.setIsQuery(GenConstants.REQUIRE);
            column.setQueryType(GenConstants.QUERY_LIKE);
        }
        // 精确查询字段
        if (ArrayUtil.containsValueIgnoreCase(GenConstants.EQ_COLUMN, column.getColumnName())) {
            column.setIsQuery(GenConstants.REQUIRE);
            column.setQueryType(GenConstants.QUERY_EQ);
        }
        return column;
    }

    public static GeneratorTable dtoToGeneratorTable(String tableName, String tableComment) {
        GeneratorTable generatorTable = new GeneratorTable();
        generatorTable.setTableName(tableName);
        generatorTable.setTableComment(tableComment);
        generatorTable.setClassName(tableNameToClassName(tableName));
        generatorTable.setPackageName(GeneratorConfig.PACKAGE_NAME);
        generatorTable.setModuleName(packageNameToModuleName(GeneratorConfig.PACKAGE_NAME));
        generatorTable.setBusinessName(tableNameToBusinessName(tableName));
        generatorTable.setFunctionName(commentToBusinessName(tableComment));
        generatorTable.setAuthor(GeneratorConfig.AUTHOR);
        return generatorTable;
    }

    private static String tableNameToClassName(String tableName) {
        // 去除前缀
        // eg: 表名: bz_sys_user  前缀: bz_ 去除后 sys_user
        if (GeneratorConfig.AUTO_REMOVE_PREFIX && StrUtil.isNotBlank(GeneratorConfig.TABLE_PREFIX)) {
            List<String> prefixList = StrUtil.split(GeneratorConfig.TABLE_PREFIX, BaseConstant.DEFAULT_SPLIT_STR);
            for (String prefix : prefixList) {
                if (tableName.startsWith(prefix)) {
                    tableName = StrUtil.removePrefix(tableName, prefix);
                    break;
                }
            }
        }
        // 下划线转驼峰 sys_user -> sysUser
        tableName = StrUtil.toCamelCase(tableName);
        // 首字符大写 sysUser -> SysUser
        return StrUtil.upperFirst(tableName);
    }

    private static String packageNameToModuleName(String packageName) {
        int lastIndex = packageName.lastIndexOf(".");
        int nameLength = packageName.length();
        return StrUtil.sub(packageName, lastIndex + 1, nameLength);
    }

    private static String tableNameToBusinessName(String tableName) {
        int lastIndex = tableName.lastIndexOf("_");
        int nameLength = tableName.length();
        return StrUtil.sub(tableName, lastIndex + 1, nameLength);
    }

    private static String commentToBusinessName(String comment) {
        // 用户表 -> 用户
        return StrUtil.isNotBlank(comment) ? StrUtil.replaceLast(comment, "表", "") : comment;
    }

    private static void setType(GeneratorTableColumn column, String columnType) {
        // varchar(50) -> varchar
        columnType = StrUtil.subBefore(columnType, "(", false);
        // 字符串 or 长文本
        if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_STR, columnType) || ArrayUtil.contains(GenConstants.COLUMN_TYPE_TEXT, columnType)) {
            // 字符串长度超过500设置为文本域
            Integer columnLength = getColumnLength(column.getColumnType());
            String htmlType = columnLength >= 500 || ArrayUtil.contains(GenConstants.COLUMN_TYPE_TEXT, columnType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
            column.setHtmlType(htmlType);
        }

        // 时间类型
        if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_TIME, columnType)) {
            column.setJavaType(GenConstants.TYPE_DATE);
            column.setHtmlType(GenConstants.HTML_DATETIME);
        }

        // 数字类型
        if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_NUMBER, columnType)) {
            // 输入框
            column.setHtmlType(GenConstants.HTML_INPUT);
            // Integer
            if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_INT, columnType)) {
                column.setJavaType(GenConstants.TYPE_INTEGER);
            }
            // Float
            else if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_FLOAT, columnType)) {
                column.setJavaType(GenConstants.TYPE_FLOAT);
            }
            // Double
            else if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_DOUBLE, columnType)) {
                column.setJavaType(GenConstants.TYPE_DOUBLE);
            }
            // BigDecimal
            else if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_BIGDECIMAL, columnType)) {
                column.setJavaType(GenConstants.TYPE_BIGDECIMAL);
            }
            // 布尔
            else if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_BIT, columnType)) {
                column.setJavaType(GenConstants.TYPE_BOOLEAN);
            }
            // Long
            else if (ArrayUtil.contains(GenConstants.COLUMN_TYPE_BIGINT, columnType)) {
                column.setJavaType(GenConstants.TYPE_LONG);
            }
            // 奇奇怪怪的类型, 就用Double接收吧~
            else {
                column.setJavaType(GenConstants.TYPE_DOUBLE);
            }
        }

        // 单选框
        if (ArrayUtil.containsValueIgnoreCase(GenConstants.HTML_RADIO_COLUMN, column.getColumnName())) {
            column.setHtmlType(GenConstants.HTML_RADIO);
        }
        // 下拉框
        if (ArrayUtil.containsValueIgnoreCase(GenConstants.HTML_SELECT_COLUMN, column.getColumnName())) {
            column.setHtmlType(GenConstants.HTML_SELECT);
        }
        // 图片上传控件
        if (ArrayUtil.containsValueIgnoreCase(GenConstants.HTML_IMAGE_COLUMN, column.getColumnName())) {
            column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD);
        }
        // 文件上传控件
        if (ArrayUtil.containsValueIgnoreCase(GenConstants.HTML_FILE_COLUMN, column.getColumnName())) {
            column.setHtmlType(GenConstants.HTML_FILE_UPLOAD);
        }
        // 富文本控件
        if (ArrayUtil.containsValueIgnoreCase(GenConstants.HTML_EDITOR_COLUMN, column.getColumnName())) {
            column.setHtmlType(GenConstants.HTML_EDITOR);
        }
    }

    /**
     * 获取字段长度
     *
     * @param columnType 列类型
     * @return 截取后的列类型
     */
    private static Integer getColumnLength(String columnType) {
        // bigint(20)
        try {
            String length = StrUtil.subBetween(columnType, "(", ")");
            return Integer.valueOf(length);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    /**
     * 生成zip文件
     */
    public static void download(HttpServletResponse response, byte[] data) throws IOException {
        response.reset();
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.addHeader("Content-Length", String.valueOf(data.length));
        response.setContentType("application/octet-stream; charset=UTF-8");
        IoUtil.write(response.getOutputStream(), true, data);
    }
}
